<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div>
    <canvas id="canvas" width="400" height="300"></canvas>
  </div>
  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    let img = new Image(), imgData, points = [], pos
    img.src = 'image.jpg'
    // img.src = 'answer.png'
    img.onload = function () {
      canvas.width = (img.width>document.body.width?document.body.width:img.width) || canvas.width
      canvas.height = (img.height>document.body.height?document.body.height:img.height) || canvas.height
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      imgData = ctx.getImageData(0, 0, canvas.width, canvas.height).data
      getPoints()
      draw()
    }

    function getPoints() {
      for (let i = 0; i < canvas.height; i++) {
        for (let j = 0; j < canvas.width; j++) {
          pos = (i * canvas.width + j) * 4
          points.push({
            xa: (canvas.width/10) * Math.random()+1 | 0,
            ya: (canvas.height/10) * Math.random()+1 | 0,
            xs: Math.random() * canvas.width | 0,
            ys: Math.random() * canvas.height | 0,
            x: j,
            y: i,
            fillStyle: `rgba(${imgData[pos]},${imgData[pos + 1]},${imgData[pos + 2]},${imgData[pos + 3]})`
          })
        }
      }
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      let continueDraw = false
      points.forEach((p, index) => {
        p.xs = Math.abs(p.xs - p.x) <= p.xa ? p.x : (p.xs + ((p.x - p.xs) > 0 ? p.xa : -p.xa))
        p.ys = Math.abs(p.ys - p.y) <= p.ya ? p.y : (p.ys + ((p.y - p.ys) > 0 ? p.ya : -p.ya))
        p.xa = p.xa + (canvas.width/100 + 1 |0)
        p.ya = p.ya + (canvas.height/100 + 1 |0)
        ctx.fillRect(p.xs, p.ys, 1, 1)
        ctx.fillStyle = p.fillStyle
        if(p.xs !== p.x || p.ys !== p.y) continueDraw = true
      })
      if(continueDraw) requestAnimationFrame(draw)
      else cancelAnimationFrame(draw)
    }

  </script>
</body>

</html>